package xml;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import palette.CanvasManager;
import palette.CanvasWindow;

import cuShapes.PQShape;

/**
 * Reads an xml file given the filename, and unmarshals it into a {@link cuShapes.ShapeList ShapeList} inside of {@link xml.ShapeCollection ShapeCollection} using the JAXB API.
 *  
 * @author mylesc,varunr
 *
 */
public class XmlReader {
	JAXBContext ctx;
	Unmarshaller xmlReader;
	ShapeCollection shapeCollection;
	
	// specify where the XML schema is located
    final File dir = new File("generated" + File.separator + "schema");
    InputStream is;
    
    /**
     * Constructor.
     */
    public XmlReader() {
    	initialize();
    }
    
    /**
     * Initializes the {@link javax.xml.bind.JAXBContext JAXBContext} with the class structure that it will be filling.
     */
    private void initialize() {
		try {
			ctx = JAXBContext.newInstance(ShapeCollection.class);
			xmlReader = ctx.createUnmarshaller();
			// generate an XML schema from the annotated object model; create it
	        // in the dir specified earlier under the default name, schema1.xsd
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
    
    /**
     * Reads in xmlFileName creating objects based on the xml file, and stores each new object in shapeCollection. 
     * @param xmlFileName
     */
    public void read(String xmlFileName) {
    	CanvasWindow currWin = (CanvasWindow) CanvasManager.getInst().getSelectedFrame();
    	
    	try {
	    	// specify a name for the generated XML instance document
    		is = new FileInputStream(new File(xmlFileName));
	        shapeCollection = (ShapeCollection) xmlReader.unmarshal(is);
        } catch (JAXBException jbe) {
            jbe.printStackTrace();
	    } catch (IOException e) {
	    	System.out.println("File not found");
	    	e.printStackTrace();
	    }
    
	    // Add all shapes read in to the currWin's shapeList
	    for(PQShape e : shapeCollection.getShapeList()) {
	    	currWin.getShapeList().add(e);    	
	    	currWin.getShapeList().update();
	    }
	    
	    // Solution for reconnecting shapes
	    for(PQShape e : currWin.getShapeList()) {
	    	e.reAddConnections();
	    	// Now update the CanvasWindow's shapeId so there are no conflicts for newly drawn shapes.
	    	if(e.getShapeId() > currWin.getShapeId()) 
	    		currWin.setShapeId((e.getShapeId())+1);
	    }

	    // Done with putting the shapes in shapeList and reconnecting all the shapes so repaint.
	    currWin.getShapeList().setCurrentShape(currWin.getShapeList().getLast());
	    currWin.getShapeList().update();
    }
}
